let oldNPages = this._grid.nPages();
this._updateAdjustment(availHeight);
- this._grid.updateSpacingForSize(availWidth, availHeight);
- this._grid.computePages(availWidth, availHeight);
- // Make sure the view doesn't have a bad adjustment value after screen size changes
- // and therefore the pages computation.
+
+ this._grid.adaptToSize(availWidth, availHeight);
+
if (this._availWidth != availWidth || this._availHeight != availHeight || oldNPages != this._grid.nPages()) {
this._verticalAdjustment.value = 0;
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this,
box = this._grid.actor.get_theme_node().get_content_box(box);
let availWidth = box.x2 - box.x1;
let availHeight = box.y2 - box.y1;
- this._grid.updateSpacingForSize(availWidth, availHeight);
+ this._grid.adaptToSize(availWidth, availHeight);
}
});
this._parentAvailableWidth = width;
this._parentAvailableHeight = height;
- this._grid.updateSpacingForSize(width, height);
+ this._grid.adaptToSize(width, height);
// Set extra padding to avoid popup or close button being cut off
this._grid.topPadding = Math.max(this._grid.topPadding - this._offsetForEachSide, 0);
let label = this._dir.get_name();
this.icon = new IconGrid.BaseIcon(label,
- { createIcon: Lang.bind(this, this._createIcon) });
+ { createIcon: Lang.bind(this, this._createIcon), setSizeManually: true });
this.actor.set_child(this.icon.actor);
this.actor.label_actor = this.icon.label;
}));
},
- _createIcon: function(size) {
- return this.view.createFolderIcon(size, this);
+ _createIcon: function(iconSize) {
+ return this.view.createFolderIcon(iconSize, this);
},
_popupHeight: function() {
iconParams = {};
iconParams['createIcon'] = Lang.bind(this, this._createIcon);
+ iconParams['setSizeManually'] = true;
this.icon = new IconGrid.BaseIcon(app.get_name(), iconParams);
this.actor.set_child(this.icon.actor);
const Clutter = imports.gi.Clutter;
const Gtk = imports.gi.Gtk;
+const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const Signals = imports.signals;
const St = imports.gi.St;
const Params = imports.misc.params;
const Tweener = imports.ui.tweener;
-const ICON_SIZE = 48;
+const ICON_SIZE = 96;
+const MIN_ICON_SIZE = 16;
const EXTRA_SPACE_ANIMATION_TIME = 0.25;
// Pulled from CSS, but hardcode some defaults here
this._spacing = 0;
this._hItemSize = this._vItemSize = ICON_SIZE;
+ this._fixedHItemSize = this._fixedVItemSize = undefined;
this._grid = new Shell.GenericContainer();
this.actor.add(this._grid, { expand: true, y_align: St.Align.START });
this.actor.connect('style-changed', Lang.bind(this, this._onStyleChanged));
// Kind of a lie, but not really an issue right now. If
// we wanted to support some sort of hidden/overflow that would
// need higher level design
- alloc.min_size = this._hItemSize + this.leftPadding + this.rightPadding;
- alloc.natural_size = nColumns * this._hItemSize + totalSpacing + this.leftPadding + this.rightPadding;
+ alloc.min_size = this._getHItemSize() + this.leftPadding + this.rightPadding;
+ alloc.natural_size = nColumns * this._getHItemSize() + totalSpacing + this.leftPadding + this.rightPadding;
},
_getVisibleChildren: function() {
if (this._rowLimit)
nRows = Math.min(nRows, this._rowLimit);
let totalSpacing = Math.max(0, nRows - 1) * this._getSpacing();
- let height = nRows * this._vItemSize + totalSpacing + this.topPadding + this.bottomPadding;
+ let height = nRows * this._getVItemSize() + totalSpacing + this.topPadding + this.bottomPadding;
alloc.min_size = height;
alloc.natural_size = height;
},
}
if (columnIndex == 0) {
- y += this._vItemSize + spacing;
+ y += this._getVItemSize() + spacing;
x = box.x1 + leftEmptySpace + this.leftPadding;
} else {
- x += this._hItemSize + spacing;
+ x += this._getHItemSize() + spacing;
}
}
},
child.get_preferred_size();
/* Center the item in its allocation horizontally */
- let width = Math.min(this._hItemSize, childNaturalWidth);
+ let width = Math.min(this._getHItemSize(), childNaturalWidth);
let childXSpacing = Math.max(0, width - childNaturalWidth) / 2;
- let height = Math.min(this._vItemSize, childNaturalHeight);
+ let height = Math.min(this._getVItemSize(), childNaturalHeight);
let childYSpacing = Math.max(0, height - childNaturalHeight) / 2;
let childBox = new Clutter.ActorBox();
let spacing = this._getSpacing();
while ((this._colLimit == null || nColumns < this._colLimit) &&
- (usedWidth + this._hItemSize <= forWidth)) {
- usedWidth += this._hItemSize + spacing;
+ (usedWidth + this._getHItemSize() <= forWidth)) {
+ usedWidth += this._getHItemSize() + spacing;
nColumns += 1;
}
},
rowsForHeight: function(forHeight) {
- return Math.floor((forHeight -(this.topPadding + this.bottomPadding) + this._getSpacing()) / (this._vItemSize + this._getSpacing()));
+ return Math.floor((forHeight - (this.topPadding + this.bottomPadding) + this._getSpacing()) / (this._getVItemSize() + this._getSpacing()));
},
usedHeightForNRows: function(nRows) {
- return (this._vItemSize + this._getSpacing()) * nRows - this._getSpacing() + this.topPadding + this.bottomPadding;
+ return (this._getVItemSize() + this._getSpacing()) * nRows - this._getSpacing() + this.topPadding + this.bottomPadding;
},
usedWidth: function(forWidth) {
- let usedWidth = this.columnsForWidth(forWidth) * (this._hItemSize + this._getSpacing());
+ return this.usedWidthForNColumns(this.columnsForWidth(forWidth));
+ },
+
+ usedWidthForNColumns: function(columns) {
+ let usedWidth = columns * (this._getHItemSize() + this._getSpacing());
usedWidth -= this._getSpacing();
return usedWidth + this.leftPadding + this.rightPadding;
},
return this._fixedSpacing ? this._fixedSpacing : this._spacing;
},
- /**
- * This function must to be called before iconGrid allocation,
- * to know how much spacing can the grid has
- */
- updateSpacingForSize: function(availWidth, availHeight) {
- let maxEmptyVArea = availHeight - this._minRows * this._vItemSize;
- let maxEmptyHArea = availWidth - this._minColumns * this._hItemSize;
+ _getHItemSize: function() {
+ return this._fixedHItemSize ? this._fixedHItemSize : this._hItemSize;
+ },
+
+ _getVItemSize: function() {
+ return this._fixedVItemSize ? this._fixedVItemSize : this._vItemSize;
+ },
+
+ _updateSpacingForSize: function(availWidth, availHeight) {
+ let maxEmptyVArea = availHeight - this._minRows * this._getVItemSize();
+ let maxEmptyHArea = availWidth - this._minColumns * this._getHItemSize();
let maxHSpacing, maxVSpacing;
if (this._padWithSpacing) {
let maxSpacing = Math.min(maxHSpacing, maxVSpacing);
// Limit spacing to the item size
- maxSpacing = Math.min(maxSpacing, Math.min(this._vItemSize, this._hItemSize));
- // The minimum spacing, regardless of whether it satisfies the row/column minima,
+ maxSpacing = Math.min(maxSpacing, Math.min(this._getVItemSize(), this._getHItemSize()));
+ // The minimum spacing, regardless of whether it satisfies the row/columng minima,
// is the spacing we get from CSS.
let spacing = Math.max(this._spacing, maxSpacing);
this.setSpacing(spacing);
if (this._padWithSpacing)
this.topPadding = this.rightPadding = this.bottomPadding = this.leftPadding = spacing;
+ },
+
+ /**
+ * This function must to be called before iconGrid allocation,
+ * to know how much spacing can the grid has
+ */
+ adaptToSize: function(availWidth, availHeight) {
+ this._fixedHItemSize = this._hItemSize;
+ this._fixedVItemSize = this._vItemSize;
+ this._updateSpacingForSize(availWidth, availHeight);
+ let spacing = this._getSpacing();
+
+ if (this.columnsForWidth(availWidth) < this._minColumns || this.rowsForHeight(availHeight) < this._minRows) {
+ let neededWidth = this.usedWidthForNColumns(this._minColumns) - availWidth ;
+ let neededHeight = this.usedHeightForNRows(this._minRows) - availHeight ;
+
+ let neededSpacePerItem = (neededWidth > neededHeight) ? Math.ceil(neededWidth / this._minColumns)
+ : Math.ceil(neededHeight / this._minRows);
+ this._fixedHItemSize = Math.max(this._hItemSize - neededSpacePerItem, MIN_ICON_SIZE);
+ this._fixedVItemSize = Math.max(this._vItemSize - neededSpacePerItem, MIN_ICON_SIZE);
+
+ if (this._fixedHItemSize < MIN_ICON_SIZE)
+ this._fixedHItemSize = MIN_ICON_SIZE;
+ if (this._fixedVItemSize < MIN_ICON_SIZE)
+ this._fixedVItemSize = MIN_ICON_SIZE;
+
+ this._updateSpacingForSize(availWidth, availHeight);
+ }
+ let scale = Math.min(this._fixedHItemSize, this._fixedVItemSize) / Math.max(this._hItemSize, this._vItemSize);
+ Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, function() { this._updateChildrenScale(scale); }));
+ },
+
+ // Note that this is ICON_SIZE as used by BaseIcon, not elsewhere in IconGrid; it's a bit messed up
+ _updateChildrenScale: function(scale) {
+ for (let i in this._items) {
+ let newIconSize = Math.floor(ICON_SIZE * scale);
+ this._items[i].icon.setIconSize(newIconSize);
+ }
}
});
rowIndex++;
}
if (columnIndex == 0) {
- y += this._vItemSize + spacing;
+ y += this._getVItemSize() + spacing;
if ((i + 1) % this._childrenPerPage == 0)
- y += this._spaceBetweenPages - spacing + this.bottomPadding + this.topPadding;
+ y += this._spaceBetweenPages - spacing + this.bottomPadding + this.topPadding;
x = box.x1 + leftEmptySpace + this.leftPadding;
- } else {
- x += this._hItemSize + spacing;
- }
+ } else
+ x += this._getHItemSize() + spacing;
}
},
- computePages: function (availWidthPerPage, availHeightPerPage) {
+ _computePages: function (availWidthPerPage, availHeightPerPage) {
let [nColumns, usedWidth] = this._computeLayout(availWidthPerPage);
let nRows;
let children = this._getVisibleChildren();
this._childrenPerPage = nColumns * this._rowsPerPage;
},
+ adaptToSize: function(availWidth, availHeight) {
+ this.parent(availWidth, availHeight);
+ this._computePages(availWidth, availHeight);
+ },
+
_availableHeightPerPageForItems: function() {
return this.usedHeightForNRows(this._rowsPerPage) - (this.topPadding + this.bottomPadding);
},